package org.linlinjava.litemall.wx.web;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.xxl.sso.core.conf.Conf;
import com.xxl.sso.core.user.XxlSsoUser;
import org.linlinjava.litemall.core.util.JacksonUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.domain.LitemallDisputeOrder;
import org.linlinjava.litemall.db.domain.LitemallOrder;
import org.linlinjava.litemall.db.domain.LitemallOrderGoods;
import org.linlinjava.litemall.db.service.LitemallDisputeService;
import org.linlinjava.litemall.db.service.LitemallOrderGoodsService;
import org.linlinjava.litemall.db.service.LitemallOrderService;
import org.linlinjava.litemall.db.util.DisputeConstant;
import org.linlinjava.litemall.db.util.OrderConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("wx/dispute")
public class WxDisputeController {
    @Autowired
    LitemallDisputeService disputeService;
    @Autowired
    LitemallOrderGoodsService orderGoodsService;
    @Autowired
    LitemallOrderService orderService;


    @PostMapping("list")
    public Object list(HttpServletRequest request, @RequestBody String msg) {
        Integer page = JacksonUtil.parseInteger(msg, "page");
        Integer pageSize = JacksonUtil.parseInteger(msg, "pageSize");
        if (page == null || pageSize == null) {
            return ResponseUtil.badArgument();
        }
        if (page < 0 || pageSize < 0) {
            return ResponseUtil.badArgumentValue();
        }
        XxlSsoUser user = (XxlSsoUser) request.getAttribute(Conf.SSO_USER);
        Integer userId = Integer.parseInt(user.getUserid());
        PageInfo<LitemallDisputeOrder> orderPageInfo = disputeService.queryOrder(userId, null, page, pageSize);
        Map<String, Object> map = new LinkedHashMap<>();
        map.put("list", orderPageInfo.getList());
        map.put("totalNum", orderPageInfo.getTotal());
        return ResponseUtil.ok(map);
    }

    /**
     * 发起退货
     * @param msg
     * @param request
     * @return
     */
    @PostMapping("refund")
    public Object refund(@RequestBody String msg, HttpServletRequest request) {
        Integer orderId = JacksonUtil.parseInteger(msg, "orderId");
        JSONObject goodsListObject = JSONObject.parseObject(msg);
        String goodsListMsg = goodsListObject.getString("goodsList");
        List<JSONObject> goodsList = JSONObject.parseArray(goodsListMsg, JSONObject.class);
        String reason = JacksonUtil.parseString(msg, "reason");
        List<String> picList = JacksonUtil.parseStringList(msg, "picList");
        Short type = JacksonUtil.parseShort(msg, "type");
        if (orderId == null || orderId < 1 || type == null || type < 1) {
            return ResponseUtil.badArgument();
        }

        LitemallOrder order = orderService.findById(orderId);
        XxlSsoUser user = (XxlSsoUser) request.getAttribute(Conf.SSO_USER);
        Integer userId = Integer.parseInt(user.getUserid());
        if (order == null || !order.getUserId().equals(userId)) {
            return ResponseUtil.unauthz();
        }

        List<LitemallDisputeOrder> orderList = disputeService.findActiveOrderByOId(orderId);
        if (orderList != null && orderList.size() > 0) {
            return ResponseUtil.fail(403, "由于您提交过该订单的退款申请，暂时无法申请，谢谢配合");
        }

        boolean legalState1 = (order.getOrderStatus().equals(OrderConstant.PAYED) && type.equals(DisputeConstant.TYPE_TIME));
        boolean legalState2 = (order.getOrderStatus().equals(OrderConstant.ASSAYED) && type.equals(DisputeConstant.TYPE_CORRECT));

        if (!legalState1 && !legalState2) {
            return ResponseUtil.fail(402, "项目状态不合法，禁止退款");
        }

        boolean insurance = order.getGoodsPrice() != null && order.getGoodsPrice().compareTo(new BigDecimal(0)) > 0;
        if (insurance) {
            type = type.equals(DisputeConstant.TYPE_TIME) ? DisputeConstant.TYPE_TIME_INSURANCE : DisputeConstant.TYPE_CORRECT_INSURANCE;
        }

        order.setOrderStatus(OrderConstant.PENDING);

        if (type.equals(DisputeConstant.TYPE_TIME) || type.equals(DisputeConstant.TYPE_TIME_INSURANCE)) {
            goodsList = new LinkedList<>();
            for (LitemallOrderGoods goods : orderGoodsService.queryByOid(orderId)) {
                JSONObject object = new JSONObject();
                object.put("num", goods.getNumber());
                object.put("orderGoodsId", goods.getId());
                goodsList.add(object);
            }
        }

        disputeService.createDispute(userId, order.getBrandId(), orderId, goodsList, reason, picList, type);
        orderService.updateWithOptimisticLocker(order);
        return ResponseUtil.ok();
    }

    /**
     * 取消
     * @param msg
     * @param request
     * @return
     */
    @PostMapping("cancel")
    public Object cancel(@RequestBody String msg, HttpServletRequest request) {
        Integer disputeId = JacksonUtil.parseInteger(msg, "disputeId");
        if (disputeId == null || disputeId < 1) {
            return ResponseUtil.badArgument();
        }
        LitemallDisputeOrder disputeOrder = disputeService.findOrderById(disputeId);
        XxlSsoUser user = (XxlSsoUser) request.getAttribute(Conf.SSO_USER);
        Integer userId = Integer.parseInt(user.getUserid());
        if (disputeOrder == null || !disputeOrder.getUserId().equals(userId)) {
            return ResponseUtil.unauthz();
        }
        boolean legalState1 = (disputeOrder.getState().equals(DisputeConstant.SUBMITTED));
        boolean legalState2 = (disputeOrder.getState().equals(DisputeConstant.REFUSED));
        if (!legalState1 && !legalState2) {
            ResponseUtil.fail(403, "该投诉单不处于合法状态，无法取消");
        }
        disputeOrder.setState(DisputeConstant.CANCELED);
        disputeService.updateWithOptimisticLocker(disputeOrder);
        LitemallOrder order = orderService.findById(disputeOrder.getOrderId());
        if (disputeOrder.getType().equals(DisputeConstant.TYPE_TIME) || disputeOrder.getType().equals(DisputeConstant.TYPE_TIME_INSURANCE)) {
            order.setOrderStatus(OrderConstant.PAYED);
        } else if (disputeOrder.getType().equals(DisputeConstant.TYPE_CORRECT) || disputeOrder.getType().equals(DisputeConstant.TYPE_CORRECT_INSURANCE)) {
            order.setOrderStatus(OrderConstant.ASSAYED);
        }
        orderService.updateWithOptimisticLocker(order);
        return ResponseUtil.ok();
    }

    /**
     * 申诉
     * @param msg
     * @param request
     * @return
     */
    @PostMapping("appeal")
    public Object appeal(@RequestBody String msg, HttpServletRequest request) {
        Integer disputeId = JacksonUtil.parseInteger(msg, "disputeId");
        String reason = JacksonUtil.parseString(msg, "reason");
        List<String> picList = JacksonUtil.parseStringList(msg, "picList");
        if (disputeId == null || disputeId < 1) {
            return ResponseUtil.badArgument();
        }
        LitemallDisputeOrder disputeOrder = disputeService.findOrderById(disputeId);
        XxlSsoUser user = (XxlSsoUser) request.getAttribute(Conf.SSO_USER);
        Integer userId = Integer.parseInt(user.getUserid());
        if (disputeOrder == null || !disputeOrder.getUserId().equals(userId)) {
            return ResponseUtil.unauthz();
        }
        if (!disputeOrder.getState().equals(DisputeConstant.REFUSED)) {
            ResponseUtil.fail(403, "该投诉单不处于合法状态，无法申诉");
        }
        disputeOrder.setState(DisputeConstant.INTERVENED);
        disputeService.updateWithOptimisticLocker(disputeOrder);
        disputeService.recording(disputeId, reason, picList, (short)0);
        return ResponseUtil.ok();
    }
}
